package cn.iocoder.yudao.module.infra.dal.mysql.deduplication;

import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.infra.dal.dataobject.deduplication.FileIndexDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

/**
 * 文件索引 Mapper（简化版本）
 *
 * @author 芋道源码
 */
@Mapper
public interface FileIndexMapper extends BaseMapperX<FileIndexDO> {

    /**
     * 根据SHA-256哈希值和大小查询文件索引
     *
     * @param sha256Hash SHA-256哈希值
     * @param size 文件大小
     * @return 文件索引记录
     */
    default FileIndexDO selectByHashAndSize(String sha256Hash, Long size) {
        return selectOne(FileIndexDO::getSha256Hash, sha256Hash,
                        FileIndexDO::getSize, size);
    }

    /**
     * 根据SHA-256哈希值查询文件索引列表
     *
     * @param sha256Hash SHA-256哈希值
     * @return 文件索引列表
     */
    default List<FileIndexDO> selectByHash(String sha256Hash) {
        return selectList(FileIndexDO::getSha256Hash, sha256Hash);
    }

    /**
     * 增加引用计数
     *
     * @param id 文件索引ID
     * @return 影响行数
     */
    @Update("UPDATE infra_file_index SET reference_count = reference_count + 1, update_time = NOW() WHERE id = #{id}")
    int incrementReferenceCount(@Param("id") Long id);

    /**
     * 减少引用计数
     *
     * @param id 文件索引ID
     * @return 影响行数
     */
    @Update("UPDATE infra_file_index SET reference_count = reference_count - 1, update_time = NOW() WHERE id = #{id} AND reference_count > 0")
    int decrementReferenceCount(@Param("id") Long id);

    /**
     * 查询引用计数为0的文件
     *
     * @param limit 限制数量
     * @return 文件索引列表
     */
    default List<FileIndexDO> selectZeroRefCountFiles(int limit) {
        return selectList(new LambdaQueryWrapperX<FileIndexDO>()
                .eq(FileIndexDO::getReferenceCount, 0)
                .last("LIMIT " + limit));
    }

    /**
     * 根据文件类型查询文件列表
     *
     * @param type 文件类型
     * @param limit 限制数量
     * @return 文件索引列表
     */
    default List<FileIndexDO> selectByType(String type, int limit) {
        return selectList(new LambdaQueryWrapperX<FileIndexDO>()
                .eq(FileIndexDO::getType, type)
                .last("LIMIT " + limit));
    }

    /**
     * 根据配置ID查询文件索引列表
     *
     * @param configId 配置ID
     * @return 文件索引列表
     */
    default List<FileIndexDO> selectListByConfigId(Long configId) {
        return selectList(FileIndexDO::getConfigId, configId);
    }

    /**
     * 统计总文件数量
     *
     * @return 总文件数量
     */
    default Long selectTotalFileCount() {
        return selectCount();
    }

    /**
     * 统计总存储大小
     *
     * @return 总存储大小（字节）
     */
    @Select("SELECT COALESCE(SUM(size), 0) FROM infra_file_index WHERE deleted = 0")
    Long selectTotalStorageSize();

    /**
     * 统计去重文件数量（引用计数>1的文件）
     *
     * @return 去重文件数量
     */
    @Select("SELECT COUNT(*) FROM infra_file_index WHERE deleted = 0 AND reference_count > 1")
    Long selectDeduplicatedFileCount();

    /**
     * 统计去重节省的存储空间
     *
     * @return 节省的字节数
     */
    @Select("SELECT COALESCE(SUM(size * (reference_count - 1)), 0) FROM infra_file_index WHERE deleted = 0 AND reference_count > 1")
    Long selectSavedStorageSize();

}
